package com.yalemang.photovalut.base.encryption;

import android.content.Context;
import android.os.Environment;
import android.util.Log;

import com.yalemang.framework.log.LogX;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableOnSubscribe;

public class EncryptionManager {

    private static String photoFatherPath;
    private static String videoFatherPath;
    private final static String PHOTO_FOLDER_NAME = "photo";
    private final static String VIDEO_FOLDER_NAME = "video";
    private final static String PHOTO_FILE_FORMAT = ".plock";
    private volatile static EncryptionManager INSTANCE;
    //必须16位要不然异常
    private final String KEY = "1234567891011120";

    private EncryptionManager() {
    }

    public static EncryptionManager getInstance() {
        if (INSTANCE == null) {
            synchronized (EncryptionManager.class) {
                if (INSTANCE == null) {
                    INSTANCE = new EncryptionManager();
                }
            }
        }
        return INSTANCE;
    }

    public void init(Context context){
        //创建包名文件夹
        File rootFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), context.getPackageName());
        //创建photo video文件夹
        File photoFolderFile = new File(rootFile.getAbsolutePath(), PHOTO_FOLDER_NAME);
        photoFatherPath = photoFolderFile.getAbsolutePath();
        File videoFolderFile = new File(rootFile.getAbsolutePath(), VIDEO_FOLDER_NAME);
        videoFatherPath = videoFolderFile.getAbsolutePath();
    }

    public String getEncryptionPhotoPath(String folderName, String photoFileName){
        File photoFolderFile = new File(photoFatherPath, folderName);
        photoFolderFile.mkdirs();
        File photoFile = new File(photoFolderFile.getAbsolutePath(), photoFileName + PHOTO_FILE_FORMAT);
        return photoFile.getAbsolutePath();
    }

    public @NonNull Observable<String> encryption(String imgPath, String resultPath) {
        return Observable.create((ObservableOnSubscribe<String>) emitter -> {
            //加密图片
            byte[] bytes = FileUtil.file2Bytes(imgPath);
            byte[] results;
            try {
                results = AESUtils.encryptData(KEY, bytes);
                //写入到文件
                FileUtil.bytes2File(results, resultPath);
                emitter.onNext(resultPath);
            } catch (Exception e) {
                emitter.onError(e);
            }
            emitter.onComplete();
        }).compose(SchedulersTransformer.io2main());
    }

    /**
     * 解密到内存
     *
     * @param imgPath
     * @return
     */
    public @NonNull Observable<byte[]> decryptView(String imgPath) {
        return Observable.create((ObservableOnSubscribe<byte[]>) emitter -> {
            byte[] bytes = FileUtil.file2Bytes(imgPath);
            byte[] results;
            try {
                results = AESUtils.decryptData(KEY, bytes);
                emitter.onNext(results);
            } catch (Exception e) {
                emitter.onError(e);
            }
            emitter.onComplete();
        }).compose(SchedulersTransformer.io2main());
    }

    /**
     * 解密到目录
     *
     * @param imgPath
     * @param resultPath
     * @return
     */
    public @NonNull Observable<String> decrypt(String imgPath, String resultPath) {
        return Observable.create((ObservableOnSubscribe<String>) emitter -> {
            byte[] bytes = FileUtil.file2Bytes(imgPath);
            byte[] results;
            try {
                results = AESUtils.decryptData(KEY, bytes);
                FileUtil.bytes2File(results, resultPath);
                emitter.onNext(resultPath);
            } catch (Exception e) {
                emitter.onError(e);
            }
        }).compose(SchedulersTransformer.io2io());
    }

    /**
     * 混入字节
     *
     * @param path
     * @return
     */
    public @NonNull Observable<VideoEncryptionBean> mixedBytes(String path, String result) {
        return Observable.create((ObservableOnSubscribe<VideoEncryptionBean>) emitter -> {
            FileInputStream fis = null;
            FileOutputStream fos = null;
            try {
                File file = new File(path);
                File resultFile = new File(result);
                if(resultFile.exists()){
                    resultFile.delete();
                }
                resultFile.createNewFile();
                fis = new FileInputStream(file);
                fos = new FileOutputStream(resultFile);
                byte[] b = new byte[1024];
                long allByte = 0;
                int n;
                while ((n = fis.read(b)) != -1) {
                    fos.write(b);
                    allByte += n;
                    Log.d("Ellen2024", "当前进度：" + allByte);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                assert fis != null;
                fis.close();
                assert fos != null;
                fos.close();
            }
            VideoEncryptionBean videoEncryptionBean = new VideoEncryptionBean();
            videoEncryptionBean.setResult(result);
            videoEncryptionBean.setJinDu(100);
            emitter.onNext(videoEncryptionBean);
            emitter.onComplete();
        }).compose(SchedulersTransformer.io2io());
    }

    /**
     * 移除字节
     *
     * @param path
     * @return
     */
    public @NonNull Observable<VideoEncryptionBean> removeBytes(String path, String result) {
        return Observable.create((ObservableOnSubscribe<VideoEncryptionBean>) emitter -> {

        }).compose(SchedulersTransformer.io2io());
    }

}
